package com.ssy.jt808.gateway.infrastructure.config;

import com.ssy.jt808.gateway.application.endpoint.JTHandlerInterceptor;
import com.ssy.jt808.protocol.codec.JTMessageAdapter;
import com.ssy.netmc.NettyConfig;
import com.ssy.netmc.Server;
import com.ssy.netmc.codec.Delimiter;
import com.ssy.netmc.codec.LengthField;
import com.ssy.netmc.core.HandlerMapping;
import com.ssy.netmc.session.SessionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @author wangzezhou
 */
@Order(Integer.MIN_VALUE)
@Configuration
@ConditionalOnProperty(value="jt808-gateway.server.enable", havingValue="true")
public class JtServerConfig{
    private final JTMessageAdapter     messageAdapter;
    private final HandlerMapping       handlerMapping;
    private final JTHandlerInterceptor handlerInterceptor;
    private final SessionManager       sessionManager;

    public JtServerConfig( JTMessageAdapter messageAdapter, HandlerMapping handlerMapping, JTHandlerInterceptor handlerInterceptor, SessionManager sessionManager ) {
        this.messageAdapter = messageAdapter;
        this.handlerMapping = handlerMapping;
        this.handlerInterceptor = handlerInterceptor;
        this.sessionManager = sessionManager;
    }

    @ConditionalOnProperty(value="jt808-gateway.server.port.tcp")
    @Bean(initMethod="start", destroyMethod="stop")
    public Server jt808TCPServer( @Value("${jt808-gateway.server.port.tcp}") int port ){
        return NettyConfig.custom()
                          .setIdleStateTime(120, 0, 0)
                          .setPort(port)
                          //标识位[2] + 消息头[21] + 消息体[1023 * 2(转义预留)]  + 校验码[1] + 标识位[2]
                          .setMaxFrameLength(2 + 21 + 1023*2 + 1 + 2)
                          .setDelimiters(new Delimiter(new byte[]{ 0x7e }, false))
                          .setDecoder(messageAdapter)
                          .setEncoder(messageAdapter)
                          .setHandlerMapping(handlerMapping)
                          .setHandlerInterceptor(handlerInterceptor)
                          .setSessionManager(sessionManager)
                          .setName("jt808-gateway-tcp")
                .build();
    }

    @ConditionalOnProperty(value="jt808-gateway.server.port.udp")
    @Bean(initMethod="start", destroyMethod="stop")
    public Server jt808UDPServer( @Value("${jt808-gateway.server.port.udp}") int port ){
        return NettyConfig.custom()
                          .setPort(port)
                          .setDelimiters(new Delimiter(new byte[]{ 0x7e }, false))
                          .setDecoder(messageAdapter)
                          .setEncoder(messageAdapter)
                          .setHandlerMapping(handlerMapping)
                          .setHandlerInterceptor(handlerInterceptor)
                          .setSessionManager(sessionManager)
                          .setName("jt808-gateway-UDP")
                          .setEnableUDP(true)
                .build();
    }

    @ConditionalOnProperty(value="jt808-gateway.alarm-file.enable", havingValue="true")
    @Bean(initMethod="start", destroyMethod="stop")
    public Server alarmFileServer( @Value("${jt808-gateway.alarm-file.port}") int port,
                                   JTMessageAdapter alarmFileMessageAdapter ){
        return NettyConfig.custom()
                          .setPort(port)
                          .setMaxFrameLength(2 + 21 + 1023*2 + 1 + 2)
                          .setLengthField(new LengthField(new byte[]{ 0x30, 0x31, 0x63, 0x64 }, 1024*65, 58, 4))
                          .setDelimiters(new Delimiter(new byte[]{ 0x7e }, false))
                          .setDecoder(alarmFileMessageAdapter)
                          .setEncoder(alarmFileMessageAdapter)
                          .setHandlerMapping(handlerMapping)
                          .setHandlerInterceptor(handlerInterceptor)
                          .setName("jt808-gateway-AlarmFile")
                .build();
    }

}